#include "common.h"

int /*__attribute__ ((long_call))*/ main(void)
{
	//void (*resetArm9)(void) = (void*)*((u32*)0x022ffffc);
	//if(resetArm9)resetArm9();
	tNDSHeader *hdr = (tNDSHeader*)0x02300000;
	void (*func_ptr)(void);
	//void (*dc_flushall)(void);
	memcpy((void*)hdr->arm9destination, (void*)(0x02300000 + hdr->arm9romOffset), hdr->arm9binarySize);
	//if(DSi_mode && *((vu32*)((int)NDSHEADER + 0x1cc)))memcpy_arm9((void*)*((vu32*)((int)0x02300000 + 0x1c8)), (void*)(0x02300000 + *((vu32*)((int)0x02300000 + 0x1c0))), *((vu32*)((int)0x02300000 + 0x1cc)));//Load the 9i bin when used.
	DC_FlushRange((void*)hdr->arm9destination, hdr->arm9binarySize);
	DC_InvalidateAll();
	IC_InvalidateAll();
	IPC_SendSync(0x0);
	while(REG_VCOUNT!=192);//Wait for a vblank before copying the header to NDSHEADER to make sure Arm7 is executing our bootstub first.
	while(REG_VCOUNT==192);

	memcpy((void*)NDSHEADER, (void*)0x02300000, 0x160);//We assume that Arm7 will be executing our bootstub by the time we're overwriting arm7executeAddress when we're copying the header to the NDSHEADER address. With DS this works fine, hopefully this works fine with DSi without adding sanity checks etc.
	/*if(DSi_mode)
	{
		memset((void*)0x02ffe000, 0, 0x1000);
		memcpy((void*)0x02ffe000, (void*)0x02300000, 0x200);
	}*/
	//if(resetArm9)resetArm9();
	BOOTFLAG = 1;
	while(BOOTFLAG!=2);
	while(REG_VCOUNT!=192);//Sync with Arm7 before jumping to the bin.
	while(REG_VCOUNT==192);
	while(BOOTFLAG!=3);
	//if(resetArm9)resetArm9();

	func_ptr = (void*)NDSHEADER->arm9executeAddress;
	func_ptr();
	while(1);//Should never happen.
	return 0;
}

void* memcpy(void* a, const void* b, size_t len)
{
	vu32 *bufa = (vu32*)a;
	vu32 *bufb = (vu32*)b;
	while(len>0)
	{
		*bufa = *bufb;
		bufa++;
		bufb++;
		len-=4;
	}
	return a;
}

void* memset(void* buffer, int val, size_t len)
{
	vu32 *buf = (vu32*)buffer;
	while(len>0)
	{
		*buf = val;
		buf++;
		len-=4;
	}
	return buffer;
}

